package com.gl.service.impl;

import com.gl.mapper.FileMapper;
import com.gl.pojo.Result;
import com.gl.pojo.entity.File;
import com.gl.service.FileService;
import com.gl.utils.AliyunOSSOperator;
import com.gl.utils.CurrentHolder;
import com.gl.utils.UuidUtils;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class FileServiceImpl implements FileService {
    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;
    @Autowired
    private VectorStore vectorStore;

    /**
     * 根据会议id和用户id获取文件信息
     *
     * @param meetingId 会议ID
     * @param userId    用户ID
     * @return -
     */
    public File getFileInfoByMeetingIdAndUserId(String meetingId, String userId) {
        if (meetingId == null || userId == null) return null;
        return fileMapper.getFileInfoByMeetingIdAndUserId(meetingId, userId);
    }

    /**
     * 上传文件
     *
     * @param meetingId     会议ID
     * @param multipartFile 文件
     */
    @Override
    @Transactional
    public void uploadFile(String meetingId, MultipartFile multipartFile) {
        if (multipartFile == null) return;
        // 获取用户id
        String userId = CurrentHolder.getCurrentId();
        // 获取文件名
        String fileName = multipartFile.getOriginalFilename();
        // 获取文件类型
        String fileType = multipartFile.getContentType();
        // 生成文件id
        String fileId = UuidUtils.getUuid();
        // 上传文件
        String fileUrl;
        try {
            // 查询会议是否已有文件
            File fileInfo = fileMapper.getFileInfoByMeetingIdAndUserId(meetingId, userId);
            if (fileInfo != null) {
                // 阿里云删除旧文件
                aliyunOSSOperator.deleteImageByUrl(fileInfo.getUrl());
                // 数据库中删除旧文件的路径
                fileMapper.deleteFileById(fileInfo.getId());
            }
            // 获取文件的地址url
            fileUrl = aliyunOSSOperator.upload(multipartFile.getBytes(), fileName);
        } catch (Exception e) {
            throw new RuntimeException("上传文件失败！");
        }
        // 文件保存
        File file = new File();
        file.setId(fileId);
        file.setName(fileName);
        file.setType(fileType);
        file.setUrl(fileUrl);
        file.setUserId(userId);
        file.setMeetingId(meetingId);
        fileMapper.insertFile(file);
    }

    @Override
    public boolean embedding(String meetingId, MultipartFile file) {
        if (file.isEmpty()) {
            return false;
        }
        try {
            // 从IO流中读取文件
            TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(new InputStreamResource(file.getInputStream()));
            // 将文本内容划分成更小的块
            List<Document> splitDocuments = new TokenTextSplitter()
                    .apply(tikaDocumentReader.read());
            // 为每个文档块附加 meeting_id 元数据
            splitDocuments = splitDocuments.stream()
                    .map(doc -> {
                        Map<String, Object> metadata = new HashMap<>(doc.getMetadata());
                        metadata.put("meeting_id", meetingId);
                        return new Document(doc.getContent(), metadata);
                    })
                    .collect(Collectors.toList());
            // 存入向量数据库，这个过程会自动调用embeddingModel,将文本变成向量再存入。
            vectorStore.add(splitDocuments);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
